package cn.org.mrliu.ssm.util;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;

import com.squareup.okhttp.Callback;
import com.squareup.okhttp.FormEncodingBuilder;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

public class HttpUtil {

	private final static OkHttpClient client = new OkHttpClient();
	public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json; charset=utf-8");

	public static Response get(String url) throws IOException {
		return get(url, new HashMap<String, Object>());
	}

	public static Response get(String url, Map<String, Object> param) throws IOException {
		System.out.println(url);
		url += buildGetParam(param);
		Request request = new Request.Builder().url(url).build();
		Response response = client.newCall(request).execute();
		if (!response.isSuccessful()) {
			throw new IOException("" + response);
		}
		return response;
	}

	public static void get(String url, Callback responseCallback) throws Exception {
		System.out.println(url);
		Request request = new Request.Builder().url(url).build();
		enqueue(request, responseCallback);
	}

	public static void get(String url, Map<String, Object> param, Callback responseCallback) throws IOException {
		System.out.println(url);
		url += buildGetParam(param);
		Request request = new Request.Builder().url(url).build();
		enqueue(request, responseCallback);
	}

	public static Response post(String url) throws IOException {
		return post(url, null);
	}

	public static Response post(String url, Map<String, Object> param) throws IOException {
		FormEncodingBuilder formEncodingBuilder = buildPostParam(param);

		RequestBody formBody = formEncodingBuilder.build();

		Request request = new Request.Builder().url(url).post(formBody).build();

		Response response = client.newCall(request).execute();
		if (!response.isSuccessful()) {
			throw new IOException("" + response);
		}
		return response;
	}

	public static void post(String url, Map<String, Object> param, Callback responseCallback) throws IOException {
		FormEncodingBuilder formEncodingBuilder = buildPostParam(param);

		RequestBody formBody = formEncodingBuilder.build();

		Request request = new Request.Builder().url(url).post(formBody).build();

		enqueue(request, responseCallback);
	}

	public static Response post(String url, String data, MediaType mediaType) throws IOException {
		RequestBody requestBody = RequestBody.create(mediaType, data);

		Request request = new Request.Builder().url(url).post(requestBody).build();

		Response response = client.newCall(request).execute();
		if (!response.isSuccessful())
			throw new IOException("" + response);
		return response;
	}

	public static void post(String url, String data, MediaType mediaType, Callback responseCallback)
			throws IOException {
		RequestBody requestBody = RequestBody.create(mediaType, data);

		Request request = new Request.Builder().url(url).post(requestBody).build();
		enqueue(request, responseCallback);
	}

	private static void enqueue(Request request, final Callback responseCallback) {
		client.newCall(request).enqueue(new Callback() {
			@Override
			public void onResponse(Response response) throws IOException {
				if (responseCallback == null) {
					return;
				}
				if (response.isSuccessful()) {
					responseCallback.onResponse(response);
				} else {
					responseCallback.onFailure(response.request(), new IOException("" + response));
				}
			}

			@Override
			public void onFailure(Request request, IOException e) {
				if (responseCallback == null) {
					return;
				}
				responseCallback.onFailure(request, e);
			}
		});
	}

	public static FormEncodingBuilder buildPostParam(Map<String, Object> param) {
		FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
		if (param != null && param.size() > 0) {
			for (Entry<String, Object> entry : param.entrySet()) {
				String key = entry.getKey();
				Object value = entry.getValue();
				if (value == null) {
					continue;
				}
				if (value.getClass().isArray()) {
					Object[] objects = (Object[]) value;
					for (Object object : objects) {
						buildPostParam(formEncodingBuilder, key, object);
					}

				} else if (value instanceof Collection) {
					@SuppressWarnings("rawtypes")
					Collection collection = (Collection) value;
					for (Object object : collection) {
						buildPostParam(formEncodingBuilder, key, object);
					}
				} else {
					buildPostParam(formEncodingBuilder, key, value);
				}
			}
		}
		return formEncodingBuilder;
	}

	public static String buildGetParam(Map<String, Object> param) {
		StringBuffer paramString = new StringBuffer();
		if (param != null && param.size() > 0) {
			for (Entry<String, Object> entry : param.entrySet()) {
				// key
				String key = entry.getKey();
				// value
				Object value = entry.getValue();
				if (value == null) {
					continue;
				}
				// 如果是数组或集合,则循环添加参数
				if (value.getClass().isArray()) {
					Object[] objects = (Object[]) value;
					for (Object object : objects) {
						buildGetParam(paramString, key, object);
					}
				} else if (value instanceof Collection) {
					@SuppressWarnings("rawtypes")
					Collection collection = (Collection) value;
					for (Object object : collection) {
						buildGetParam(paramString, key, object);
					}
				} else {
					// 单个值,直接拼接参数
					buildGetParam(paramString, key, value);
				}
			}
			// 将第一个&号替换成?号
			paramString.replace(0, 1, "?");

		}
		System.out.println(paramString);
		return paramString.toString();
	}

	private static void buildGetParam(StringBuffer paramString, String key, Object value) {
		paramString.append("&");
		paramString.append(key);
		paramString.append("=");
		paramString.append(value);
	}

	private static void buildPostParam(FormEncodingBuilder formEncodingBuilder, String key, Object value) {
		if (value == null) {
			return;
		}
		formEncodingBuilder.add(key, String.valueOf(value));
	}

	public static void main(String[] args) throws IOException {
		// FormEncodingBuilder formEncodingBuilder = new FormEncodingBuilder();
		// formEncodingBuilder.add("names", "A");
		// formEncodingBuilder.add("names", "B");
		// formEncodingBuilder.add("names", "C");

		Map<String, Object> param = new LinkedHashMap<>();
		param.put("names", new String[]{"A","B","123"});
		FormEncodingBuilder formEncodingBuilder = buildPostParam(param);
		RequestBody formBody = formEncodingBuilder.build();

		String url = "http://localhost:8080/ssm-maven-project/param/test.json";
		Request request = new Request.Builder().url(url).post(formBody).build();

		Response response = client.newCall(request).execute();
		if (!response.isSuccessful()) {
			throw new IOException("" + response);
		}
		System.out.println(response.body().string());

		// Map<String, Object> param = new LinkedHashMap<>();
		// param.put("userName", "admin");
		// param.put("password", "123456");
		// param.put("checkCode", new String[] { "ABCD", "1234" });
		//// buildGetParam(param);
		// FormEncodingBuilder formEncodingBuilder = buildPostParam(param);
		// System.out.println(formEncodingBuilder.toString());
		// post("", "", HttpUtil.MEDIA_TYPE_JSON, null);
		// String result;
		// try {
		// result = get("http://www.mrliu.org.cn", null);
		// System.out.println(result);
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
		// Map<String, Object> param = new HashMap<>();
		// param.put("userName", "admin");
		// param.put("password", "123456");
		// param.put("checkCode", "369258");
		// get("http://www.mrliu.org.cn", param, new Callback() {
		//
		// @Override
		// public void onResponse(Response response) throws IOException {
		// System.out.println("onResponse....");
		// System.out.println(response.body().string());
		// }
		//
		// @Override
		// public void onFailure(Request request, IOException e) {
		// System.out.println("onFailure.....");
		// }
		// });
		// String string = buildGetParam(param);
		// System.out.println(string);
		// System.out.println(URLEncoder.encode(string, "UTF-8"));
	}
}
